﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Compiler.CompilerLogic
{
    [Serializable]
    public class Variable
    {
        public string Value;
        public int Type;
        public int Level;
        public int LUsed = 0;

        public Variable(string value, int type, int level)
        {
            Value = value;
            Type = type;
            Level = level;
        }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            return ((Variable)obj).Value == Value && ((Variable)obj).Type == Type
                   && ((Variable)obj).Level == Level;
        }
    }

    [Serializable]
    public class Constant
    {
        public string Value;

        public Constant(string value)
        {
            Value = value;
        }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            return ((Constant)obj).Value == Value;
        }

    }

    [Serializable]
    public class Lexem
    {
        public string Value;
        public int Index;

        public Lexem(string value, int index)
        {
            Value = value;
            Index = index;
        }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            return ((Lexem)obj).Value == Value && ((Lexem)obj).Index == Index;
        }
    }


    [Serializable]
    public class LexicalTables
    {
        public List<Variable> variableTable = new List<Variable>();
        public List<Constant> constantTable = new List<Constant>();
        public List<Lexem> lexemTable = new List<Lexem>();
        public List<string> Errors; 

        public LexicalTables(FileStream fileStream)
        {
            var scanner = new Scanner(fileStream);
            var parser = new Parser(scanner);
            Errors = parser.errors.ErrorsList;
            parser.tab = new SymbolTable(parser);
            parser.gen = new CodeGenerator();
            parser.Parse();
            //var codeGen = new CodeGen();
            ///////////////////////////////////////////////////////
            foreach (Token toks in scanner.TokenList)
            {
                // Console.WriteLine(toks.val+" "+toks.kind);
                int index;
                switch (toks.kind)
                {
                    case 2:
                        index = 0;
                        break;
                    case 1:
                        index = 1;
                        break;
                    default:
                        index = 2;
                        break;
                }
                if (toks.val != "")
                {
                    lexemTable.Add(new Lexem(toks.val, index));
                }

                if (toks.kind == 2 && constantTable.Find(x => x.Value == toks.val) == null)
                    constantTable.Add(new Constant(toks.val));
            }
            foreach (Obj obj in parser.tab.SymbolList)
            {
                //Console.WriteLine(obj.name +" "+obj.type + " " + obj.level);
                variableTable.Add(new Variable(obj.name, obj.type, obj.level));
            }
            //////////////////////////////////////////////////////////
        }
    }
}
